package Communication;

import java.io.FileInputStream;
import java.io.IOException;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.util.Properties;

public class ClientSender implements IClientSender {
	private AddressMachine am;
    private static ClientSender instance;
    private String direccionServidor;
    private String friendNick;
    private String nick;
    private int puertoCliente;
    private int puertoServidor;
    private Registry registro;
    private InterfazReceptorMensajes rmiServidor; 

    public static ClientSender getInstance ( ) {
		if ( instance == null )
			instance = new ClientSender ( );
		return instance;
	}
    
    private ClientSender ( ) {
    	Properties properties = new Properties ( );
    	try {
    		properties.load ( new FileInputStream ( "conexion.properties" ) );
    	    direccionServidor = properties.getProperty ( "serverName" );
    	    puertoServidor = Integer.parseInt ( properties.getProperty ( "serverPort" ) );
    	    puertoCliente = Integer.parseInt ( properties.getProperty ( "clientPort" ) );
    	    nick = properties.getProperty ( "nick" );
    	    friendNick = properties.getProperty ( "friendNick" );
    		try {
    			String ip = InetAddress.getLocalHost ( ).toString ( );
        	    am = new AddressMachine ( nick, ip, puertoCliente );
    		} catch ( UnknownHostException e ) {
    			e.printStackTrace ( );
    		}
    	} catch (IOException e) {
    		System.out.println ( "File not found" );
    	}
    	abrirConexion ( );
    }

    public void abrirConexion ( ) {
        try {
            // obtener el registro
            registro = LocateRegistry.getRegistry ( direccionServidor, puertoServidor );
            // creando el objeto remoto
            rmiServidor = (InterfazReceptorMensajes) registro.lookup ( "rmiServidor" );
        } catch ( RemoteException e ) {
            e.printStackTrace ( );
        } catch ( NotBoundException e ) {
            e.printStackTrace ( );
        }
    }

	public void enviarMensaje ( Message mensaje ) {
		Message lookup = new Message ( );
		lookup.setType ( Message.LOOKUP );
		lookup.setNickTo ( friendNick );
		lookup.setFrom ( am );
		Message response = null;
		try {
			response = rmiServidor.recibirMensaje ( lookup );
		} catch (RemoteException e1) {
			e1.printStackTrace();
			return;
		}
		if ( response.getType() == Message.FAIL ){
			Buffer.getInstance ( ).addMessage ( response );
			return;
		}

		String s[] = response.getBody ( ).split ( " " );
		
        try {
            // obtener el registro
        	Registry registroFriend = LocateRegistry.getRegistry ( s[0].split("/")[0], Integer.parseInt ( s[1] ) );
            // creando el objeto remoto
            IClientReceiver rc = (IClientReceiver) registroFriend.lookup ( "rmiChat" );
    		mensaje.setType ( Message.CHAT );
    		mensaje.setFrom ( am );
    		mensaje.setNickTo ( friendNick );
            rc.recibirMensaje ( mensaje );
        } catch ( RemoteException e ) {
            e.printStackTrace ( );
        } catch ( NotBoundException e ) {
            e.printStackTrace ( );
        }
    }

	public void registrar ( ) {
		Message m = new Message ( );
		m.setFrom ( am ); 
		m.setType ( Message.REGISTER );
        try {
            // llamando el metodo remoto
            rmiServidor.recibirMensaje ( m );
        } catch ( RemoteException re ) {
            re.printStackTrace ( );
        }
	}
}
